﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Atacadao.Comum.Pesquisa;
using Atacadao.Servico.Entidades;
using System.Web.Helpers;
using System.Data;
using Atacadao.DB.Repositorio;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using Atacadao.Comum.DAL;

namespace Atacadao.Web.Controllers
{
    [SessionState(System.Web.SessionState.SessionStateBehavior.Required)]
    public class BaseController<TEntity> : Controller where TEntity : class, IClasseDados, new()
    {

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
        }

        protected override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            base.OnResultExecuted(filterContext);

            IGerenciadorContexto contexto = ConfiguradorRepositorio.GerenciadorDB();

            contexto.LiberarInstacia();
        }

        public ActionResult T1()
        {
            return View();
        }

        public ActionResult T2()
        {
            return RedirectToAction("T1");
        }

        public BaseController()
        {

        }

         public ActionResult Lista()
        {
            ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

            IEnumerable<TEntity> lista = servico.RecuperarTodos();

            ViewBag.QuantidadeTotal = servico.RecuperarTodos().Count();
            ViewBag.PaginaAtual = 0;

            this.ViewBag.Lista = lista;

            return View();
        }

         public ActionResult Excluir(int id)
         {

             try
             {
                 ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

                 servico.Excluir(id);

                 servico.Salvar();

                 return Content("Registro excluído com sucesso.");              

             }
             catch (Exception ex)
             {
                 return Content("Erro ao excluir registro.");
             }

         }

        //
        // GET: /Pessoa/Create
        public ActionResult Editar(int? id)
         {
             try
             {
                 if (!id.HasValue) return View();

                ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

                TEntity entidade = servico.RecuperarPorID(id);

                return View(entidade);

             }
             catch (Exception ex)
             {
                 ModelState.AddModelError("", "Erro ao Atualizar os dados.");
             }

             return View();
        }

        //
        // POST: /Pessoa/Create

        [HttpPost]
        public ActionResult Editar(TEntity entidade)
        {
            
            try
            {
                bool alterar = true;

                IClasseDados iclsDados = (IClasseDados)entidade;

                var chaves = (from f in iclsDados.ValoresChave where f == null select f).Count();

                if (chaves > 0) { alterar = false; }

                foreach (string item in iclsDados.NomeChave)
	            {
                    this.ModelState.Remove(item);
	            }
                
                if (ModelState.IsValid)
                {
                    ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

                    if (alterar)
                    {
                        servico.Alterar(entidade); 
                    }
                    else
                    {
                        servico.Incluir(entidade);
                    }

                    return RedirectToAction("Lista");
                }

            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", "Erro ao Atualizar os dados.");
            }

            return View();
        }

        [HttpPost]
        public ActionResult Pesquisa()
        {
            NameValueCollection form = this.Request.Form;

            int quantidadeTotal = 0;
            int paginaAtual = 0;

            string ordem = this.Request.QueryString["ordGr"];

            List<TEntity> lista = this.OnBeforeExecutarPesquisa(form, ordem, out quantidadeTotal,out paginaAtual).ToList();
            ViewBag.QuantidadeTotal = quantidadeTotal;
            ViewBag.PaginaAtual = paginaAtual;

            return PartialView("ListaParcial",lista);
        }

        protected IQueryable<TEntity> OnBeforeExecutarPesquisa(NameValueCollection form, string ordenar, out int quantidadeTotal, out int paginaAtual)
        {
            var parametros = from p in form.AllKeys
                             where p.StartsWith("p_hd")
                             select p;

            List<CampoPesquisa> campos = new List<CampoPesquisa>();

            string nomeControlePesquisa = null;
            string[] valoresAuxiliares = null;
            int valorHiddenPesquisa = 0;
            //string ordenar = string.Empty;

            if (form.AllKeys.Contains("hdpgl") && !string.IsNullOrEmpty(form["hdpgl"])) valorHiddenPesquisa = int.Parse(form["hdpgl"]);
            //if (form.AllKeys.Contains("hdordl")) ordenar = form["hdordl"];

            paginaAtual = valorHiddenPesquisa;

            foreach (string item in parametros)
            {
                
                List<string> valores = new List<string>();

                nomeControlePesquisa = item.Replace("p_hd", "");

                if (!string.IsNullOrEmpty(form[nomeControlePesquisa]))
                {
                    valoresAuxiliares = form[item].Split('|');
                    CampoPesquisa campo = new CampoPesquisa();
                    campo.TipoPesquisa = (TipoPesquisa)Enum.Parse(typeof(TipoPesquisa), valoresAuxiliares[0]);
                    campo.Campo = valoresAuxiliares[1];
                    campo.Campo2 = valoresAuxiliares[2];

                    valores.Add(form[campo.Campo]);


                    if (!string.IsNullOrEmpty(campo.Campo2) && string.IsNullOrEmpty(form[campo.Campo2]))
                    {
                        valores.Add(form[campo.Campo2]);
                    }

                    campo.Valores = valores;

                    campos.Add(campo);
                                    
                }


            }

            return OnExecutarPesquisa(campos, form, valorHiddenPesquisa, ordenar, out quantidadeTotal);
        }

        protected IQueryable<TEntity> OnExecutarPesquisa(List<CampoPesquisa> campos, NameValueCollection form, int pagina, string ordenar, out int quantidadeTotal)
        {
            ServicoBase<TEntity> servico = new ServicoBase<TEntity>();

            return servico.Recuperar(campos, ordenar, pagina, 10, out quantidadeTotal);
        }


        public string ViewAsString(string nomeView, object model, Dictionary<string, object> valoresViewData)
        {
            StringWriter sw = default(StringWriter);
            StringBuilder sb = new StringBuilder();

            sw = new StringWriter(sb);

            ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, nomeView, "");

            ViewDataDictionary dicionarioViewDataDictionary = new ViewDataDictionary(model);
            TempDataDictionary tempData = new TempDataDictionary();

            if ((valoresViewData != null))
            {
                foreach (string chave in valoresViewData.Keys)
                {
                    dicionarioViewDataDictionary.Add(chave, valoresViewData[chave]);
                }
            }

            this.ViewData.Model = model;

            ViewContext viewContext = new ViewContext(ControllerContext, result.View, dicionarioViewDataDictionary, tempData, sw);

            result.View.Render(viewContext, sw);

            return sb.ToString();

        }


    }
}
